/*
 * CMapDrawItems.java
 *
 * Created on March 10, 2007, 6:58 PM
 *
 * Copyright 2008 David D. Emory
 * 
 * This file is part of Five Points. See <http://www.fpdev.org> for
 * additional information regarding the project.
 * 
 * Five Points is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Five Points is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.fpdev.apps.admin.gui.map;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.fpdev.core.transit.TransitPath;
import org.fpdev.apps.admin.gui.*;

/**
 *
 * @author demory
 */
public class MapDrawItems {

  private Map<String, DrawItemInfo> items_;
  private List<DrawItemInfo> priorityList_;
  
  // codes for standard drawable items:
  public static final String AN_TRANSIT_PATH = "aTPath";
  public static final String AN_ACCESS_PATH = "aAccPath";
  public static final String AN_CURRENT_LOCATION = "aCurLoc";
  public static final String RTE_TRANSIT_PATH = "rTPath";
  public static final String DIVERSION_PATH = "diversionPath";
  public static final String STATION = "station";
  public static final String IMP_ROUTE_PREVIEW = "impRtePreview";
  public static final String IMP_ROUTE_LINKSET = "impRteShpLinkSet";
  public static final String IMP_ROUTE_STARTNODE = "impRteShpStartNode";
  public static final String IMP_ROUTE_ENDNODE = "impRteShpEndNode";
  public static final String IMP_ROUTE_HIGHLIGHT_PATH = "impRteShpHighlightPath";
  public static final String IMP_ROUTE_HIGHLIGHT_ENDPOINT = "impRteShpHighlightEndpoint";
  public static final String IMP_ROUTE_MAIN_PATH = "impRteShpMainPath";
  public static final String SEARCH_NODE = "searchNode";
  public static final String BEST_TRIP = "bestTrip";
  public static final String BEST_TRIP_START = "bestTripStart";
  public static final String BEST_TRIP_END = "bestTripEnd";

  /** Creates a new instance of CMapDrawItems */
  public MapDrawItems() {
    items_ = new HashMap<String, DrawItemInfo>();
    priorityList_ = new LinkedList<DrawItemInfo>();
  }

  public MapDrawable getItem(String key) {
    DrawItemInfo item = items_.get(key);
    if (item != null) {
      return item.getItem();
    }
    return null;
  }

  public void addItem(String key, MapDrawable item, String modes) {
    addItem(key, item, modes, 0);
  }

  public void addItem(String key, MapDrawable item, String modes, int priority) {
    //System.out.println("adding item p="+priority);
    DrawItemInfo itemInfo = new DrawItemInfo(item, key, modes, priority);
    if (items_.containsKey(key)) {
      priorityList_.remove(items_.get(key));
    }
    items_.put(key, itemInfo);
    priorityList_.add(itemInfo);
    //System.out.println(" added "+key+" w/ p="+priority);
    Collections.sort(priorityList_);
  //System.out.println("i size = "+items_.size()+" pl size = "+priorityList_.size());
  }

  public void removeAll() {
    items_.clear();
    priorityList_.clear();
  }

  public void removeItem(String key) {
    if (items_.containsKey(key)) {
      DrawItemInfo item = items_.get(key);
      items_.remove(key);
      priorityList_.remove(item);
    }
  }

  public void removeFromPrefix(String prefix) {
    for(String key : new HashSet<String>(items_.keySet()))
      if(key.startsWith(prefix)) removeItem(key);
  }

  public void draw(MapCanvas canvas, ACGUI.Mode mode) {
    //List<DrawItemInfo> list = new LinkedList<DrawItemInfo>(items_.values());


    for (Iterator<DrawItemInfo> items = priorityList_.iterator(); items.hasNext();) {
      DrawItemInfo item = items.next();
      //System.out.println(" drawing "+item.getKey());
      if (item.hasMode(mode)) {
        item.getItem().draw(canvas);
      }
    }
  }

  public void transitPathItemUpdated(TransitPath path) {
    for (Iterator<DrawItemInfo> items = items_.values().iterator(); items.hasNext();) {
      DrawItemInfo item = items.next();
      if (item.getItem() instanceof TransitPath && ((TransitPath) item.getItem()).getSubRoute().getMasterID().equals(path.getSubRoute().getMasterID()))  {
        //System.out.println("updating path drawitem for "+((TransitPath) item.getItem()).getSubRoute().getMasterID());
        item.setItem(path);
      }
    }
  }

  private class DrawItemInfo implements Comparable {

    private MapDrawable item_;
    private String key_,  modes_;
    private Integer priority_;

    public DrawItemInfo(MapDrawable item, String key, String modes, int priority) {
      item_ = item;
      key_ = key;
      modes_ = modes;
      priority_ = new Integer(priority);
    }

    public MapDrawable getItem() {
      return item_;
    }

    public void setItem(MapDrawable item) {
      item_ = item;
    }

    public String getKey() {
      return key_;
    }

    public boolean hasMode(ACGUI.Mode mode) {
      String modeChar = "";
      switch (mode) {
        case ANALYSIS:
          modeChar = "a";
          break;
        case MAP:
          modeChar = "m";
          break;
        case ROUTE:
          modeChar = "r";
          break;
        case STATION:
          modeChar = "s";
          break;
      }
      return modes_.contains("*") || modes_.contains(modeChar);
    }

    public int compareTo(Object o) {
      return priority_.compareTo(((DrawItemInfo) o).priority_);
    }
  }
}
